package com.module.ble.widget

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import com.common.app.utls.TimeUtils
import com.common.base.app.extras.no
import com.common.base.app.extras.otherwise
import com.common.base.app.extras.yes
import com.common.base.utils.ViewUtils
import com.common.base.utils.ViewUtils.dp2px
import com.common.base.utils.ViewUtils.sp2px
import com.module.ble.R
import com.module.ble.data.bean.CusChartData

/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：2025/07/12
 *
 * 描述：烛台图表控件
 * 支持自定义Y轴阶段配置、X轴时间标签、触摸交互、平均值曲线和背景柱等功能
 * 修订历史：
 *
 */
class CandlestickChart @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // 触摸监听器接口
    interface OnBarTouchListener {
        fun onBarTouched(index: Int, minValue: Float, maxValue: Float, timeLabel: String, extStr: String)
        fun onAverageLineTouched(index: Int, minValue: Float, maxValue: Float, timeLabel: String, extStr: String)
        fun onTouchReleased()
    }

    // 画笔
    private val barPaint = Paint(Paint.ANTI_ALIAS_FLAG) // 柱状图画笔
    private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG) // 文字画笔
    private val yAxisTextPaint = Paint(Paint.ANTI_ALIAS_FLAG) // Y轴标记文字画笔
    private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG) // 背景画笔
    private val touchLinePaint = Paint(Paint.ANTI_ALIAS_FLAG) // 触摸实线画笔
    private val averageLinePaint = Paint(Paint.ANTI_ALIAS_FLAG) // 平均值曲线画笔
    private val backgroundBarPaint = Paint(Paint.ANTI_ALIAS_FLAG) // 背景柱画笔

    // 矩形区域
    private val rectF = RectF()

    // 数据相关
    private var dataValues = mutableListOf<CusChartData>()
    private var averageDataValues = mutableListOf<CusChartData>()
    private val timeLabels = arrayOf("00:00", "06", "12", "18", "24:00")

    // Y轴阶段配置（可从外部设置）
    private var yAxisStages = floatArrayOf(0f, 50f, 100f) // 默认三个阶段

    // 触摸相关
    private var touchListener: OnBarTouchListener? = null
    private var isTouching = false
    private var touchedBarIndex = -1
    private var touchLineX = 0f

    // 颜色配置
    private var activeBarColor = ViewUtils.getColor(R.color.c_5282ff) // 蓝色
    private var inactiveBarColor = ViewUtils.getColor(R.color.color_d9d9d9) // 灰色
    private var textColor = ViewUtils.getColor(R.color.c_7f7f7f)
    private var gridLineColor = ViewUtils.getColor(R.color.color_d9d9d9)
    private var chartBackgroundColor = ViewUtils.getColor(R.color.color_FAFAFA) // 柱状图背景色
    private var touchLineColor = ViewUtils.getColor(R.color.black) // 触摸实线颜色
    private var averageLineColor = ViewUtils.getColor(R.color.red) // 平均值曲线颜色

    // 尺寸配置
    private var barSpacing = dp2px(1f)
    private var textSize = sp2px(12f)
    private var chartPaddingTop = dp2px(5f)
    private var chartPaddingBottom = dp2px(30f)

    // Y轴色块相关尺寸
    private var yAxisTextSize = sp2px(10f) // Y轴标记文字大小
    private var yAxisTextMargin = dp2px(5f) // 标记文字距离右边的间距

    private var yAxisTextEx:String?= "" // Y轴mark文字拼接内容

    // 柱子圆角控制变量
    private var enableBarTopRounding = true // 控制柱子顶部圆角
    private var enableBarBottomRounding = true // 控制柱子底部圆角

    // X轴中间线控制变量
    private var enableXAxisSolidLine = false // 控制X轴中间线绘制方式

    private var isTouchEnabled = true // 触摸总开关，默认开启

    private var drawBackgroundBarsByDataValues = true  //以哪个数据来绘制背景


    init {
        // 获取自定义属性
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CandlestickChart)
        activeBarColor = typedArray.getColor(R.styleable.CandlestickChart_signs_candlestick_barDefaultColor, activeBarColor)
        averageLineColor = typedArray.getColor(R.styleable.CandlestickChart_signs_candlestick_averageLineColor, averageLineColor)
        yAxisTextEx = typedArray.getString(R.styleable.CandlestickChart_signs_candlestick_y_exText)
        typedArray.recycle()

        // 初始化画笔
        textPaint.color = textColor
        textPaint.textSize = textSize
        textPaint.textAlign = Paint.Align.CENTER

        // 初始化Y轴标记文字画笔
        yAxisTextPaint.color = textColor
        yAxisTextPaint.textSize = yAxisTextSize
        yAxisTextPaint.textAlign = Paint.Align.LEFT

        // 初始化背景画笔
        backgroundPaint.color = chartBackgroundColor
        backgroundPaint.style = Paint.Style.FILL

        // 初始化触摸实线画笔
        touchLinePaint.color = touchLineColor
        touchLinePaint.strokeWidth = dp2px(1f)
        touchLinePaint.style = Paint.Style.STROKE

        // 初始化平均值曲线画笔
        averageLinePaint.color = averageLineColor
        averageLinePaint.strokeWidth = dp2px(2f)
        averageLinePaint.style = Paint.Style.STROKE
        averageLinePaint.strokeCap = Paint.Cap.ROUND
        averageLinePaint.strokeJoin = Paint.Join.ROUND

        // 初始化背景柱画笔
        backgroundBarPaint.color = ViewUtils.getColor(R.color.color_d9d9d9)
        backgroundBarPaint.style = Paint.Style.FILL

        // 初始化默认数据（48个空数据点）
        initializeDefaultData()
    }

    /**
     * 初始化默认数据
     */
    private fun initializeDefaultData() {
        dataValues.clear()
        averageDataValues.clear()
//        repeat(48) {
//            dataValues.add(CusChartData(createdTime = 0L, mValue = 0f))
//            averageDataValues.add(CusChartData(createdTime = 0L, mValue = 0f))
//        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val width = MeasureSpec.getSize(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)

        // 计算最小高度
        val minHeight = (chartPaddingTop + chartPaddingBottom + dp2px(200f)).toInt()
        val height = when (heightMode) {
            MeasureSpec.EXACTLY -> MeasureSpec.getSize(heightMeasureSpec)
            else -> minHeight
        }

        setMeasuredDimension(width, height)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        val chartHeight = height - chartPaddingTop - chartPaddingBottom

        // 绘制柱状图背景
        drawChartBackground(canvas, chartHeight)

        // 绘制Y轴网格线
        drawYAxisGrid(canvas, chartHeight)

        // 绘制X轴网格线
        drawXAxisGrid(canvas, chartHeight)

        // 绘制柱状图（包含背景柱）
        drawBars(canvas, chartHeight)

        // 绘制平均值曲线
        drawAverageLine(canvas, chartHeight)

        // 绘制触摸实线（在柱状图之后绘制，确保在最上层）
        if (isTouching && touchedBarIndex >= 0) {
            drawTouchLine(canvas, chartHeight)
        }

        // 绘制X轴时间标签
        drawTimeLabels(canvas, chartHeight)

        // 绘制右侧Y轴标记文字
        drawYAxisStageIndicators(canvas, chartHeight)
    }

    /**
     * 绘制柱状图背景
     */
    private fun drawChartBackground(canvas: Canvas, chartHeight: Float) {
        // 计算Y轴文字区域的位置（去除色块宽度）
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 绘制背景矩形
        rectF.set(
            0f, // 左边界
            chartPaddingTop, // 上边界
            yAxisBarX, // 右边界（到Y轴文字左侧）
            chartPaddingTop + chartHeight // 下边界
        )
        canvas.drawRect(rectF, backgroundPaint)
    }

    /**
     * 绘制Y轴网格线
     */
    private fun drawYAxisGrid(canvas: Canvas, chartHeight: Float) {
        // 计算Y轴文字区域的位置（去除色块宽度）
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 柱状图起始位置（左对齐）
        val barsStartX = 0f

        // 网格线右边界：Y轴标记文字的右侧
        val gridLineEndX = yAxisBarX + yAxisTextMargin + maxTextWidth

        // 创建虚线画笔
        val dashedLinePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
            color = gridLineColor
            strokeWidth = dp2px(1f)
            pathEffect = android.graphics.DashPathEffect(floatArrayOf(dp2px(2f), dp2px(3f)), 0f)
        }

        // 创建加粗实线画笔（用于顶部和底部）
        val boldLinePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
            color = gridLineColor
            strokeWidth = dp2px(1f) // 加粗线条
        }

        // 获取Y轴范围
        val minValue = yAxisStages.first()
        val maxValue = yAxisStages.last()
        val valueRange = maxValue - minValue

        // 绘制Y轴网格线
        for (i in yAxisStages.indices) {
            val stage = yAxisStages[i]
            val normalizedStage = (stage - minValue) / valueRange

            when (i) {
                0 -> {
                    // 底部网格线（最小值）- 绘制在柱状图下方
                    val bottomY = chartPaddingTop + chartHeight + dp2px(1f) // 在图表底部下方1dp处
                    canvas.drawLine(
                        barsStartX,
                        bottomY,
                        gridLineEndX,
                        bottomY,
                        boldLinePaint
                    )
                }
                yAxisStages.size - 1 -> {
                    // 顶部网格线（最大值）- 加粗实线
                    val y = chartPaddingTop + chartHeight * (1 - normalizedStage) - dp2px(1f)
                    canvas.drawLine(
                        barsStartX,
                        y,
                        gridLineEndX,
                        y,
                        boldLinePaint
                    )
                }
                else -> {
                    // 中间的网格线 - 虚线
                    val y = chartPaddingTop + chartHeight * (1 - normalizedStage)
                    canvas.drawLine(
                        barsStartX,
                        y,
                        yAxisBarX,
                        y,
                        dashedLinePaint
                    )
                }
            }
        }
    }

    /**
     * 绘制X轴网格线
     */
    private fun drawXAxisGrid(canvas: Canvas, chartHeight: Float) {
        // 计算Y轴文字区域的位置（去除色块宽度）
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 计算所有barSpacing的总宽度
        val totalSpacingWidth = (dataValues.size - 1) * barSpacing

        // 计算每条柱子的宽度
        val barWidth = (yAxisBarX - totalSpacingWidth) / dataValues.size

        // 柱状图起始位置（左对齐）
        val startX = 0f

        // 计算总的柱状图宽度
        val totalBarWidth = dataValues.size * barWidth + totalSpacingWidth

        // 根据开关选择绘制方式
        if (enableXAxisSolidLine) {
            // 绘制实线画笔
            val solidLinePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
                color = gridLineColor
                strokeWidth = dp2px(1f)
                style = Paint.Style.STROKE
            }

            // 绘制X轴网格线（包括首尾的时间标签位置）
            for (i in timeLabels.indices) {
                val barIndex = when (i) {
                    0 -> 0 // 00:00
                    1 -> 12 // 06:00
                    2 -> 24 // 12:00
                    3 -> 36 // 18:00
                    4 -> 47 // 24:00 (最后一个)
                    else -> 0
                }

                val gridLineX = if (i == 0) {
                    // 第一个标签（00:00）与第一个柱子的左边对齐
                    startX
                } else if (i == timeLabels.size - 1) {
                    // 最后一个标签（24:00）位于最右侧
                    startX + totalBarWidth
                } else {
                    // 其他标签位于对应柱子的中心
                    startX + barIndex * (barWidth + barSpacing) + barWidth / 2
                }

                // 计算底部Y轴线的位置
                val bottomYAxisLine = chartPaddingTop + chartHeight + dp2px(1f)

                // 绘制从底部Y轴线开始向上8px高度的垂直实线
                canvas.drawLine(
                    gridLineX,
                    bottomYAxisLine, // 从底部Y轴线开始
                    gridLineX,
                    bottomYAxisLine - dp2px(8f), // 向上8px高度
                    solidLinePaint
                )
            }
        } else {
            // 创建虚线画笔用于X轴网格线
            val xAxisGridPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
                color = gridLineColor
                strokeWidth = dp2px(1f)
                pathEffect = android.graphics.DashPathEffect(floatArrayOf(dp2px(2f), dp2px(3f)), 0f)
            }

            // 绘制X轴网格线（除首尾的时间标签位置）
            for (i in 1 until timeLabels.size - 1) { // 跳过首尾（i=0和i=4）
                val barIndex = when (i) {
                    1 -> 12 // 06:00
                    2 -> 24 // 12:00
                    3 -> 36 // 18:00
                    else -> 0
                }

                // 计算网格线的X位置（对应柱子的中心）
                val gridLineX = startX + barIndex * (barWidth + barSpacing) + barWidth / 2

                // 绘制从图表顶部到底部的垂直虚线
                canvas.drawLine(
                    gridLineX,
                    chartPaddingTop, // 图表顶部
                    gridLineX,
                    chartPaddingTop + chartHeight, // 图表底部
                    xAxisGridPaint
                )
            }
        }
    }

    /**
     * 绘制柱状图（包含背景柱）
     */
    private fun drawBars(canvas: Canvas, chartHeight: Float) {
        // 计算Y轴文字区域的位置（去除色块宽度）
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 计算所有barSpacing的总宽度
        val totalSpacingWidth = (dataValues.size - 1) * barSpacing

        // 计算每条柱子的宽度
        val barWidth = (yAxisBarX - totalSpacingWidth) / dataValues.size

        // 柱状图起始位置（左对齐）
        val startX = 0f

        // 获取Y轴范围
        val yAxisMinValue = yAxisStages.first()
        val yAxisMaxValue = yAxisStages.last()
        val yAxisValueRange = yAxisMaxValue - yAxisMinValue

        // 计算圆角半径（取柱子宽度的一半，但不超过4dp）
        val cornerRadius = (barWidth / 2).coerceAtMost(dp2px(4f))

        // 先绘制背景柱
        drawBackgroundBars(canvas, chartHeight, startX, barWidth, yAxisMinValue, yAxisMaxValue, yAxisValueRange)

        // 绘制烛台条
        for (i in dataValues.indices) {
            val dataMinValue = dataValues[i].minValue
            val dataMaxValue = dataValues[i].mValue

            // 限制数据值在Y轴有效范围内
            val clampedMinValue = dataMinValue.coerceIn(yAxisMinValue, yAxisMaxValue)
            val clampedMaxValue = dataMaxValue.coerceIn(yAxisMinValue, yAxisMaxValue)

            // 将数据值映射到图表坐标
            val normalizedMinValue = if (yAxisValueRange > 0) (clampedMinValue - yAxisMinValue) / yAxisValueRange else 0f
            val normalizedMaxValue = if (yAxisValueRange > 0) (clampedMaxValue - yAxisMinValue) / yAxisValueRange else 0f

            // 计算烛台条的Y坐标（注意Y轴是倒置的）
            var barTop = chartPaddingTop + chartHeight * (1 - normalizedMaxValue)
            var barBottom = chartPaddingTop + chartHeight * (1 - normalizedMinValue)

            // 优化：当mValue和minValue都大于0且相等时，设置烛台最小高度为4像素
            if (dataMaxValue > 0f && dataMinValue > 0f && dataMaxValue == dataMinValue) {
                val minBarHeight = 4f // 最小柱子高度为4像素
                if (barBottom - barTop < minBarHeight) {
                    barTop = barBottom - minBarHeight
                }
            }
            // 根据最大值选择颜色
            barPaint.color = activeBarColor

            val left = startX + i * (barWidth + barSpacing)
            val right = left + barWidth

            // 根据圆角控制变量决定绘制方式
            rectF.set(left, barTop, right, barBottom)

            if (enableBarTopRounding && enableBarBottomRounding) {
                // 顶部和底部都有圆角
                canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, barPaint)
            } else if (enableBarTopRounding && !enableBarBottomRounding) {
                // 只有顶部圆角
                drawRoundRectTopOnly(canvas, rectF, cornerRadius, barPaint)
            } else if (!enableBarTopRounding && enableBarBottomRounding) {
                // 只有底部圆角
                drawRoundRectBottomOnly(canvas, rectF, cornerRadius, barPaint)
            } else {
                // 没有圆角，绘制普通矩形
                canvas.drawRect(rectF, barPaint)
            }
        }
    }

    /**
     * 绘制只有顶部圆角的矩形
     */
    private fun drawRoundRectTopOnly(canvas: Canvas, rect: RectF, radius: Float, paint: Paint) {
        val path = Path()
        path.addRoundRect(
            rect,
            floatArrayOf(radius, radius, radius, radius, 0f, 0f, 0f, 0f),
            Path.Direction.CW
        )
        canvas.drawPath(path, paint)
    }

    /**
     * 绘制只有底部圆角的矩形
     */
    private fun drawRoundRectBottomOnly(canvas: Canvas, rect: RectF, radius: Float, paint: Paint) {
        val path = Path()
        path.addRoundRect(
            rect,
            floatArrayOf(0f, 0f, 0f, 0f, radius, radius, radius, radius),
            Path.Direction.CW
        )
        canvas.drawPath(path, paint)
    }

    /**
     * 绘制背景柱
     */
    private fun drawBackgroundBars(canvas: Canvas, chartHeight: Float, startX: Float, barWidth: Float, yAxisMinValue: Float, yAxisMaxValue: Float, yAxisValueRange: Float) {
        var backgroundStart = -1
        var backgroundEnd = -1

        for (i in (if(drawBackgroundBarsByDataValues) dataValues else averageDataValues).indices) {
            val isSelected = (if(drawBackgroundBarsByDataValues) dataValues else averageDataValues)[i].selectBg

            if (isSelected) {
                if (backgroundStart == -1) {
                    backgroundStart = i
                }
                backgroundEnd = i
            } else {
                if (backgroundStart != -1) {
                    // 绘制连续的背景柱
                    drawContinuousBackground(canvas, chartHeight, startX, barWidth, backgroundStart, backgroundEnd)
                    backgroundStart = -1
                    backgroundEnd = -1
                }
            }
        }

        // 处理最后一段背景柱
        if (backgroundStart != -1) {
            drawContinuousBackground(canvas, chartHeight, startX, barWidth, backgroundStart, backgroundEnd)
        }
    }

    /**
     * 绘制连续的背景柱
     */
    private fun drawContinuousBackground(canvas: Canvas, chartHeight: Float, startX: Float, barWidth: Float, startIndex: Int, endIndex: Int) {
        val left = startX + startIndex * (barWidth + barSpacing)
        val right = startX + (endIndex + 1) * (barWidth + barSpacing) - barSpacing
        val top = chartPaddingTop
        val bottom = chartPaddingTop + chartHeight

        rectF.set(left, top, right, bottom)
        canvas.drawRect(rectF, backgroundBarPaint)
    }

    /**
     * 绘制平均值曲线
     */
    private fun drawAverageLine(canvas: Canvas, chartHeight: Float) {
        if (averageDataValues.isEmpty()) return

        // 计算Y轴文字区域的位置
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 计算所有barSpacing的总宽度
        val totalSpacingWidth = (averageDataValues.size - 1) * barSpacing

        // 计算每条柱子的宽度
        val barWidth = (yAxisBarX - totalSpacingWidth) / averageDataValues.size

        // 柱状图起始位置（左对齐）
        val startX = 0f

        // 获取Y轴范围
        val yAxisMinValue = yAxisStages.first()
        val yAxisMaxValue = yAxisStages.last()
        val yAxisValueRange = yAxisMaxValue - yAxisMinValue

        // 将数据分段，遇到-1时断开
        val segments = mutableListOf<MutableList<Pair<Float, Float>>>()
        var currentSegment = mutableListOf<Pair<Float, Float>>()

        for (i in averageDataValues.indices) {
            val averageValue = averageDataValues[i].mValue

            // 如果值为-1，结束当前段并开始新段
            if (averageValue == -1f) {
                if (currentSegment.isNotEmpty()) {
                    segments.add(currentSegment)
                    currentSegment = mutableListOf()
                }
                continue
            }

            // 跳过其他无效数据点（小于等于0但不是-1）
            if (averageValue <= 0f) continue

            // 限制数据值在Y轴有效范围内
            val clampedValue = averageValue.coerceIn(yAxisMinValue, yAxisMaxValue)

            // 将数据值映射到图表坐标
            val normalizedValue = if (yAxisValueRange > 0) (clampedValue - yAxisMinValue) / yAxisValueRange else 0f

            // 计算点的坐标
            val pointX = startX + i * (barWidth + barSpacing) + barWidth / 2
            val pointY = chartPaddingTop + chartHeight * (1 - normalizedValue)

            currentSegment.add(Pair(pointX, pointY))
        }

        // 添加最后一段（如果有）
        if (currentSegment.isNotEmpty()) {
            segments.add(currentSegment)
        }

        // 绘制每个段的平滑曲线
        for (segment in segments) {
            // 如果段中有效点少于2个，无法绘制曲线
            if (segment.size < 2) continue

            // 创建路径用于绘制平滑曲线
            val path = Path()

            // 移动到第一个点
            path.moveTo(segment[0].first, segment[0].second)

            // 如果只有两个点，直接连线
            if (segment.size == 2) {
                path.lineTo(segment[1].first, segment[1].second)
            } else {
                // 使用贝塞尔曲线绘制平滑曲线
                for (i in 1 until segment.size) {
                    val currentPoint = segment[i]
                    val previousPoint = segment[i - 1]

                    // 计算控制点
                    val controlPointX1: Float
                    val controlPointY1: Float
                    val controlPointX2: Float
                    val controlPointY2: Float

                    if (i == 1) {
                        // 第一段曲线
                        val nextPoint = if (i + 1 < segment.size) segment[i + 1] else currentPoint
                        controlPointX1 = previousPoint.first + (currentPoint.first - previousPoint.first) * 0.3f
                        controlPointY1 = previousPoint.second
                        controlPointX2 = currentPoint.first - (nextPoint.first - previousPoint.first) * 0.3f
                        controlPointY2 = currentPoint.second
                    } else if (i == segment.size - 1) {
                        // 最后一段曲线
                        val prevPrevPoint = segment[i - 2]
                        controlPointX1 = previousPoint.first + (currentPoint.first - prevPrevPoint.first) * 0.3f
                        controlPointY1 = previousPoint.second
                        controlPointX2 = currentPoint.first - (currentPoint.first - previousPoint.first) * 0.3f
                        controlPointY2 = currentPoint.second
                    } else {
                        // 中间段曲线
                        val nextPoint = segment[i + 1]
                        val prevPrevPoint = segment[i - 2]
                        controlPointX1 = previousPoint.first + (currentPoint.first - prevPrevPoint.first) * 0.3f
                        controlPointY1 = previousPoint.second
                        controlPointX2 = currentPoint.first - (nextPoint.first - previousPoint.first) * 0.3f
                        controlPointY2 = currentPoint.second
                    }

                    // 绘制贝塞尔曲线
                    path.cubicTo(
                        controlPointX1, controlPointY1,
                        controlPointX2, controlPointY2,
                        currentPoint.first, currentPoint.second
                    )
                }
            }

            // 绘制路径
            canvas.drawPath(path, averageLinePaint)
        }
    }

    /**
     * 绘制触摸实线
     */
    private fun drawTouchLine(canvas: Canvas, chartHeight: Float) {
        // 绘制垂直触摸线
        canvas.drawLine(
            touchLineX,
            chartPaddingTop,
            touchLineX,
            chartPaddingTop + chartHeight,
            touchLinePaint
        )
    }

    /**
     * 绘制X轴时间标签
     */
    private fun drawTimeLabels(canvas: Canvas, chartHeight: Float) {
        // 计算Y轴文字区域的位置（去除色块宽度）
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 计算所有barSpacing的总宽度
        val totalSpacingWidth = (dataValues.size - 1) * barSpacing

        // 计算每条柱子的宽度
        val barWidth = (yAxisBarX - totalSpacingWidth) / dataValues.size

        // 柱状图起始位置（左对齐）
        val startX = 0f

        // 计算总的柱状图宽度
        val totalBarWidth = dataValues.size * barWidth + totalSpacingWidth

        val labelY = chartPaddingTop + chartHeight + dp2px(20f)

        // 绘制时间标签（每6小时一个，对应12个柱子的间隔）
        for (i in timeLabels.indices) {
            val barIndex = when (i) {
                0 -> 0 // 00:00
                1 -> 12 // 06:00
                2 -> 24 // 12:00
                3 -> 36 // 18:00
                4 -> 47 // 24:00 (最后一个)
                else -> 0
            }

            val labelX = if (i == 0) {
                // 第一个标签（00:00）与第一个柱子的左边对齐
                startX
            } else if (i == timeLabels.size - 1) {
                // 最后一个标签（24:00）位于最右侧
                startX + totalBarWidth
            } else {
                // 其他标签位于对应柱子的中心
                startX + barIndex * (barWidth + barSpacing) + barWidth / 2
            }

            // 第一个标签使用左对齐，其他标签使用居中对齐
            if (i == 0) {
                val originalAlign = textPaint.textAlign
                textPaint.textAlign = Paint.Align.LEFT
                canvas.drawText(timeLabels[i], labelX, labelY, textPaint)
                textPaint.textAlign = originalAlign
            } else {
                canvas.drawText(timeLabels[i], labelX, labelY, textPaint)
            }
        }
    }

    /**
     * 绘制右侧Y轴标记文字（去除色块）
     */
    private fun drawYAxisStageIndicators(canvas: Canvas, chartHeight: Float) {
        // 动态计算最大文字宽度
        val maxTextWidth = calculateMaxYAxisTextWidth()

        // 计算总的指示器宽度（去除色块宽度）
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth

        // Y轴文字的X位置：从控件最右边往左计算
        val yAxisTextX = width - totalIndicatorWidth

        // 获取Y轴范围
        val minValue = yAxisStages.first()
        val maxValue = yAxisStages.last()
        val valueRange = maxValue - minValue

        // 绘制所有阶段的标记文字（包括第一个起始值）
        for (i in yAxisStages.indices) {
            val stage = yAxisStages[i]

            // 计算网格线的Y位置
            val normalizedStage = (stage - minValue) / valueRange
            val gridLineY = when (i) {
                0 -> {
                    // 底部网格线位置（在图表底部下方1dp处）
                    chartPaddingTop + chartHeight + dp2px(1f)
                }
                yAxisStages.size - 1 -> {
                    // 顶部网格线位置（在图表顶部上方1dp处）
                    chartPaddingTop + chartHeight * (1 - normalizedStage) - dp2px(1f)
                }
                else -> {
                    // 中间网格线位置
                    chartPaddingTop + chartHeight * (1 - normalizedStage)
                }
            }

            // 计算文字的Y位置
            val textMetrics = yAxisTextPaint.fontMetrics
            val textHeight = textMetrics.descent - textMetrics.ascent

            val textY = when (i) {
                0 -> {
                    // 底部标记文字：显示在底部粗实线的上方
                    gridLineY - textMetrics.descent - dp2px(2f)
                }
                yAxisStages.size - 1 -> {
                    // 顶部标记文字：显示在顶部粗实线的下方
                    gridLineY - textMetrics.ascent + dp2px(2f)
                }
                else -> {
                    // 中间标记文字：与网格线垂直居中对齐
                    gridLineY - textMetrics.ascent - textHeight / 2
                }
            }

            val textX = yAxisTextX + yAxisTextMargin

            // 使用阶段值的toString()作为标签，去掉小数点后的0
            val label = if (stage % 1.0f == 0.0f) {
                stage.toInt().toString()
            } else {
                stage.toString()
            }
            canvas.drawText(if(yAxisTextEx.isNullOrEmpty()) label else "$label$yAxisTextEx", textX, textY, yAxisTextPaint)
        }
    }

    /**
     * 计算Y轴标记文字的最大宽度
     */
    private fun calculateMaxYAxisTextWidth(): Float {
        var maxTextWidth = 0f
        // 计算所有阶段值作为标签的宽度（包括第一个起始值）
        for (i in yAxisStages.indices) {
            val label = if (yAxisStages[i] % 1.0f == 0.0f) {
                yAxisStages[i].toInt().toString()
            } else {
                yAxisStages[i].toString()
            }
            val textWidth = yAxisTextPaint.measureText(label)
            if (textWidth > maxTextWidth) {
                maxTextWidth = textWidth + dp2px(14f)//给Y轴标记文字右边添加固定边距
            }
        }
        return maxTextWidth
    }

    private fun findViewPager2(): androidx.viewpager2.widget.ViewPager2? {
        var parent = parent
        while (parent != null) {
            if (parent is androidx.viewpager2.widget.ViewPager2) {
                return parent
            }
            parent = parent.parent
        }
        return null
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {

        // 如果触摸开关关闭，直接透传到父视图
        if (!isTouchEnabled) {
            return super.onTouchEvent(event)
        }

        if (dataValues.isNullOrEmpty() && averageDataValues.isNullOrEmpty()) return true//无数据是直接透传触摸

        val viewPager2 = findViewPager2()

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                if (isTouchInChartArea(event.x, event.y)) {
                    // 直接禁用ViewPager2的用户输入
                    viewPager2?.isUserInputEnabled = false
                    parent?.requestDisallowInterceptTouchEvent(true)
                    handleTouch(event.x)
                    return true
                }
            }
            MotionEvent.ACTION_MOVE -> {
                if (isTouching && isTouchInChartArea(event.x, event.y)) {
                    handleTouch(event.x)
                    return true
                }
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                if (isTouching) {
                    // 恢复ViewPager2的用户输入
                    viewPager2?.isUserInputEnabled = true
                    parent?.requestDisallowInterceptTouchEvent(false)
                    handleTouchRelease()
                    return true
                }
            }
        }
        return super.onTouchEvent(event)
    }

    /**
     * 检查触摸点是否在图表区域内
     */
    private fun isTouchInChartArea(x: Float, y: Float): Boolean {
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        return x >= 0 && x <= yAxisBarX &&
                y >= chartPaddingTop && y <= height - chartPaddingBottom
    }

    /**
     * 处理触摸事件
     */
    private fun handleTouch(touchX: Float) {
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        val totalSpacingWidth = ((if(drawBackgroundBarsByDataValues) dataValues else averageDataValues).size - 1) * barSpacing
        val barWidth = (yAxisBarX - totalSpacingWidth) / (if(drawBackgroundBarsByDataValues) dataValues else averageDataValues).size
        val startX = 0f

        // 找到最接近的柱子
        var closestIndex = -1
        var minDistance = Float.MAX_VALUE

        for (i in (if(drawBackgroundBarsByDataValues) dataValues else averageDataValues).indices) {
            val barCenterX = startX + i * (barWidth + barSpacing) + barWidth / 2
            val distance = kotlin.math.abs(touchX - barCenterX)
            if (distance < minDistance) {
                minDistance = distance
                closestIndex = i
            }
        }

        if (closestIndex >= 0 && closestIndex < (if(drawBackgroundBarsByDataValues) dataValues else averageDataValues).size) {
            touchedBarIndex = closestIndex
            touchLineX = startX + closestIndex * (barWidth + barSpacing) + barWidth / 2
            isTouching = true

            dataValues.isNullOrEmpty().no {
                // 通知监听器
                val data = dataValues[closestIndex]
                val timeLabel = getTimeLabel(closestIndex)
                touchListener?.onBarTouched(closestIndex, data.minValue, data.mValue, timeLabel,"${
                    TimeUtils.getHourMinute(
                        data.createdTime
                    )
                }-${TimeUtils.getHourMinute(data.endTime)}")
            }

            averageDataValues.isNullOrEmpty().no {
                val averageData = averageDataValues[closestIndex]
                touchListener?.onAverageLineTouched(closestIndex, averageData.minValue, averageData.mValue, "${
                    TimeUtils.getHourMinute(
                        averageData.createdTime
                    )
                }-${TimeUtils.getHourMinute(averageData.endTime)}", averageData.exStr)
            }
            invalidate()
        }
    }

    /**
     * 处理触摸释放事件
     */
    private fun handleTouchRelease() {
        isTouching = false
        touchedBarIndex = -1
        touchListener?.onTouchReleased()
        invalidate()
    }

    /**
     * 根据索引获取时间标签
     */
    private fun getTimeLabel(index: Int): String {
        val hour = index / 2 // 每小时2个数据点
        val minute = if (index % 2 == 0) "00" else "30"
        return String.format("%02d:%s", hour, minute)
    }

    // 公共方法

    /**
     * 设置Y轴阶段配置
     */
    fun setYAxisStages(stages: FloatArray) {
        yAxisStages = stages
        invalidate()
    }

    /**
     * 设置数据
     */
    fun setData(data: List<CusChartData>) {
        dataValues.clear()
        dataValues.addAll(data)
        invalidate()
    }

    /**
     * 获取数据
     */
    fun getData():List<CusChartData> {
        return dataValues
    }

    /**
     * 设置平均值数据
     */
    fun setAverageData(data: List<CusChartData>) {
        averageDataValues.clear()
        averageDataValues.addAll(data)
        invalidate()
    }

    /**
     * 设置颜色
     */
    fun setColors(activeColor: Int, inactiveColor: Int) {
        activeBarColor = activeColor
        inactiveBarColor = inactiveColor
        invalidate()
    }

    /**
     * 设置平均值曲线颜色
     */
    fun setAverageLineColor(color: Int) {
        averageLineColor = color
        averageLinePaint.color = color
        invalidate()
    }

    /**
     * 设置触摸监听器
     */
    fun setOnBarTouchListener(listener: OnBarTouchListener?) {
        touchListener = listener
    }

    /**
     * 设置柱子顶部圆角
     * @param enable true: 启用顶部圆角, false: 禁用顶部圆角
     */
    fun setBarTopRounding(enable: Boolean) {
        enableBarTopRounding = enable
        invalidate()
    }

    /**
     * 设置柱子底部圆角
     * @param enable true: 启用底部圆角, false: 禁用底部圆角
     */
    fun setBarBottomRounding(enable: Boolean) {
        enableBarBottomRounding = enable
        invalidate()
    }

    /**
     * 设置柱子圆角（同时控制顶部和底部）
     * @param enableTop 是否启用顶部圆角
     * @param enableBottom 是否启用底部圆角
     */
    fun setBarRounding(enableTop: Boolean, enableBottom: Boolean) {
        enableBarTopRounding = enableTop
        enableBarBottomRounding = enableBottom
        invalidate()
    }

    /**
     * 设置X轴中间线绘制方式
     * @param enable true: 绘制8px高度的实线, false: 绘制点虚线
     */
    fun setXAxisSolidLineEnabled(enable: Boolean) {
        enableXAxisSolidLine = enable
        invalidate()
    }

    /**
     * 获取X轴中间线绘制方式
     * @return true: 实线模式, false: 虚线模式
     */
    fun isXAxisSolidLineEnabled(): Boolean {
        return enableXAxisSolidLine
    }
    /**
     * 设置以哪个数据来绘制背景
     * @param enable true: dataValues, false: averageDataValues
     */
    fun setDrawBackgroundBarsByDataValues(enable: Boolean) {
        drawBackgroundBarsByDataValues = enable
        invalidate()
    }


    /**
     * 设置触摸开关
     * @param enabled true为启用触摸，false为禁用触摸
     */
    fun setTouchEnabled(enabled: Boolean) {
        if (isTouchEnabled != enabled) {
            isTouchEnabled = enabled
            // 如果禁用触摸时正在触摸，需要重置触摸状态
            if (!enabled && isTouching) {
                isTouching = false
                touchedBarIndex = -1
                touchListener?.onTouchReleased()
                invalidate()
            }
        }
    }

    /**
     * 获取触摸开关状态
     */
    fun isTouchEnabled(): Boolean = isTouchEnabled
}